#include "pch.h"
#include "D3DBuffer.h"

using namespace DXBase;
using namespace DXBase::D3D;

using namespace Platform;
using namespace Microsoft::WRL;

void Buffer::LoadDXData()
{
	auto np = initData ? initData->Mem : nullptr;
	if (!np)
	{
		buffer = nullptr;
		return;
	}
	if (desc.ByteWidth != np->ByteSize)
		ClearDXData();
	if (buffer)
		return;

	if (!Context)
		throw ExHelper::CreateException(ErrorCodes::ContextNotSet);
	auto device = Context->m_d3dDevice.Get();
	if (!device)
		throw ExHelper::CreateException(ErrorCodes::ContextNotReady);

	desc.ByteWidth = np->ByteSize;
	D3D11_SUBRESOURCE_DATA bufdata = { (void*)np->Data, initData->MemRowPitch, initData->MemSlicePitch };
	HR2Ex(device->CreateBuffer(&desc, &bufdata, &buffer));
}
// only update existing buffer, if there is no buffer, no update, it will be done in LoadDXData()
void Buffer::UpdateBuffer()
{
	if (!buffer)
		return;
	auto np = initData ? initData->Mem : nullptr;
	if (!np || np->ByteSize != desc.ByteWidth)
	{
		buffer = nullptr;
		return;
	}
	Context->m_d3dContext->UpdateSubresource(buffer.Get(), 0, NULL, (void*)np->Data,  initData->MemRowPitch, initData->MemSlicePitch);
}

ComPtr<ID3D11Buffer> Buffer::GetUpdatedBuffer()
{
	UpdateBuffer();
	LoadDXData();
	return buffer;
}

NativeShaderResourceView^ Buffer::GetNativeShaderResourceView()
{
	LoadDXData();
	if (!shaderResView)
	{
		throw ref new NotImplementedException("TODO");
	}
	return shaderResView;
}
NativeResource^ Buffer::GetNativeResource()
{
	LoadDXData();
	if (!nresource)
		nresource = ref new NativeResource(buffer);
	return nresource;
}

